本文章將包含以下內容
本小節將透過回顧useRef的範例以及ref加註在component的error message來回推使用forwardRef的使用時機。
回顧一下useRef的用法,useRef用來存取實際DOM元素,以下透過ref的props可以得到實際DOM的element。
function App() {
const divRefContrainer = useRef(null);
return (
<div className="test" ref={divRefContrainer}>嗨</div>
)
}
那如果我們嘗試著將ref加到Component的話會發生什麼事呢?
觀看以下範例
import React, { useRef } from "react";
function InputField({ ref }) {
return <input type="text" ref={ref} />;
}
export default function App() {
const inputRef = useRef();
return (
<div className="App">
<InputField ref={inputRef} />
</div>
);
}
如下圖
因此當我們想要讓父元件存取子元件的ref
的時候就得需要forwardRef將其子元件的ref暴露給父元件使用
。
詳細說明可以參考
根據react Beta官方的解釋如下
forwardRef lets your component expose a DOM node to parent component with a ref.
大致意思是
如果想要讓父元件可以存取到子元件的DOM節點(DOM node)的話就得仰賴forwardRef的幫助,定義完component給fowardRef進行傳遞後,在父元件就能拿到子元件的節點了。
import React, { useRef, forwardRef } from "react";
const ForwardRefMyInput = forwardRef(
function InputField(props, ref) {
return (
<>
<input {...props}
ref={ref}
type="text" />
</>
);
}
)
export default function App() {
const inputRef = useRef();
const clickHandler = () => {
console.log(inputRef.current);
}
return (
<div className="App">
<ForwardRefMyInput ref={inputRef} />
<button onClick={clickHandler}>按鈕</button>
</div>
);
}
最後就能如願印出input元件了。
本小節將實現一個useImperativeHandle的範例來解說useImperativeHandle的使用方式
通常可以讓父元件得到子元件某些自定義方法,根據react官方文件,此hook應當與forwordRef一起使用,換句話說,如果想要使用useImperativeHandle的話就得與useRef、forwardRef一起使用。
觀看以下程式碼
import React, { useRef, forwardRef, useImperativeHandle } from "react";
const ForwardRefMyInput = forwardRef(
function InputField(props, ref) {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
}
}));
return (
<>
<input {...props}
ref={inputRef}
type="text" />
</>
);
}
)
export default function App() {
const parentInputRef = useRef();
const clickHandler = () => {
console.log(parentInputRef.current);
}
return (
<div className="App">
<ForwardRefMyInput ref={parentInputRef} />
<button onClick={clickHandler}>按鈕</button>
</div>
);
}
透過自定義的function叫做focus函式回傳,我們父層就能透過宣告useRef的方式拿取子元件所暴露的方法,最後如下圖。
當我們元件裡面有許多元素的時候
可以透過useImperativeHandle限制
子元素所暴露的方法
另一方面也理解成指定
useImperativeHandle所暴露的方法。
達到
透過父元件操控子元件指定的DOM屬性。
當我們實際在撰寫react的時候,如果要透過父元件操控子元件的某些屬性或方法的時候就得考慮useImperativeHandle或forwardRef
以上如果解說有誤歡迎糾正。